<?php

class stg_Game
{
	protected $_name;
	protected $_universe;
	protected $_turn = 0;

	protected $_server;
	protected $_players = array();

	var $past_universes = array();

	function __construct($name, $universe_name, $server)
	{
		e('Building game');
		$this->universe = new stg_Universe($universe_name);
	}

	function execute_turn()
	{
		ein("Executing turn $this->turn");

		ein('Saving current universe');
		$this->past_universes[$this->turn] = clone $this->universe;
		eout();

		$orders = array();

		ein('Generating universe movement');
		$orders = array_merge($orders, $this->universe->movement());
		eout();

		ein('Opening players\' movements');
		foreach ($this->universe->players as $k=>$p)
			$orders = array_merge($orders, $p->movement);
		e(count($orders).' orders');
		ein('Sorting all orders');
		eout();
		//usort($orders, 'stg_Universe::order_compare');
		eout();

		ein('Executing orders');
		foreach ($orders as $o)
			$o->execute();
		eout();

		ein('Score generation');
		$this->universe->assign_scores();
		eout();

		ein('Testing for game finish');
		$is_finished = $this->universe->is_finished();
		eout();

		ein('Known universe generation');
		foreach ($this->universe->players as $p)
			$p->known_universe = $this->universe->known_universe_for($p);
		eout();

		eout("Turn $this->turn executed!");

		$this->increment_turn();
	}

	function increment_turn()
	{
		$this->_turn++;
	}

	function create_rule($name)
	{
		$this->rules[$name] = new stg_Rule();
		return $this->rules[$name];
	}

	function create_player($name, $user, $faction)
	{
		$this->players[$name] = new stg_Player($name, $this, $user, $faction);
		return $this->players[$name];
	}

	function create_object($name)
	{
		$this->objects[$name] = new stg_Object();
		return $this->objects[$name];
	}

	public function& __get($name)
	{
		if (method_exists($this, "get_$name"))
		{
			$result = call_user_func(array(&$this, "get_$name"));
			return $result;
		}
		elseif (property_exists($this, "_$name"))
		{
			return $this->{'_'.$name};
		}
		else
		{
			throw new Exception("Property $name does not exist in class ".get_class($this)."!!");
		}
	}

	public function __set($name, $val)
	{
		if (array_key_exists("_$name",get_object_vars($this)))
		{
			$caller_class = get_caller_class();
			$caller_object = get_caller_object();
			if (property_exists($this, '__permissions'))
			{
				$perms = $this->__permissions;
			}
			else
			{
				$perms = array();
			}
			if  (
			    get_class($this) == $caller_class ||
				is_subclass_of($this, $caller_class) ||
			    is_writable_by($caller_object, $perms, $name)
				)
			{
				if (method_exists($this, "set_$name"))
				{
					call_user_func(array(&$this, "set_$name"), $val);
				}
				else
				{
					$this->{"_$name"} = $val;
				}
			}
			else
			{
				throw new Exception("Property $name in class ".get_class($this)." is not writable by ".get_caller_class()." instances");
			}
		}
		else
		{
			throw new Exception("Property $name does not exist in class ".get_class($this)."!!");
		}
	}

}

?>
